home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / anwendungen / gw print / structurebrowser_v1.3 / sb.doc < prev    next >
Text File  |  1994-05-20  |  29KB  |  500 lines

  1. Aug 13, 1988
  2. Note:
  3.  
  4.    The version of Structure Browser in this archive is 1.3, which differs
  5.    from the earlier release in supporting more structures (nearly all of
  6.    Intuition, plus some structures from the Layers and Graphics libraries),
  7.    and in supporting the TWM tiny window standard. The process for adding new
  8.    structures to those known by SB is as described below.
  9.  
  10.    Nick Sullivan
  11.    Chris Zamara
  12.    
  13.    Transactor for the Amiga
  14.  
  15. -----------------------------------------------------------------------------
  16.  
  17.  
  18. (This article introducing Structure Browser appeared in The Transactor,
  19.  Volume 7 Issue 6. It has been edited slightly to reflect Version 1.2 of SB.)
  20.  
  21.      The Transactor Structure Browser
  22.      By Chris Zamara and Nick Sullivan
  23.  
  24. - Your guided tour through the system
  25.  
  26.  
  27. With this program and the information given in this article, you will
  28. gain knowledge about your Amiga that you yearned for, but
  29. couldn't find. This knowledge will make you a better programmer, almost
  30. certainly making you more prosperous than you would have been otherwise.
  31. With all of your extra money, you can buy more expensive computer
  32. hardware and advance yourself even further.
  33.  
  34. You will be successful, and
  35. that success will give you greater self-confidence. People will turn to
  36. you for advice and you will help out many others who would like to be as
  37. clever and successful as yourself. By helping these people, not only will
  38. you gain deep personal fulfillment, but you will become quite popular and
  39. well-liked, which certainly can't hurt your sex life.
  40.  
  41. Since so many
  42. people will be looking up to you and following your advice, you will
  43. wield quite a bit of power in the computer community and in your business
  44. dealings in general. By feeling good about yourself, you will certainly
  45. get into better physical shape and will definitely live longer - maybe up
  46. to three hundred years!
  47.  
  48. In short, reading this article and typing in the
  49. program at the end will give you knowledge, power, success and
  50. prosperity. It will improve your sex life and give you greater self
  51. esteem and a feeling of usefulness. You will be able to buy lots of
  52. expensive computer hardware, and fast cars as well if you wish. You will
  53. live longer.
  54.  
  55. But the choice is yours - read this article and make those
  56. changes in your life, or skip past it and possibly never realize the
  57. enormous potential that you know is inside of you.
  58.  
  59.  
  60. *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
  61.  
  62. If you want to learn more about the Amiga's system structures, or you'd
  63. like an easy way to look at vital data about programs while they execute,
  64. you'll make good use of the Transactor Structure Browser.
  65.  
  66. If you read our Amiga programming article in the last issue, you learned
  67. how important the various system structures are, since they are the key
  68. to finding out about all entities known to the system, like tasks,
  69. screens, windows, gadgets and the like. Structures in the Amiga are the
  70. equivalent of a memory map on a single-tasking machine, since there are
  71. no fixed memory locations on the Amiga.
  72.  
  73. The structure has a direct C-language implementation, but we can speak of
  74. a structure template (the definition of the structure) independently of
  75. a language. A structure is just the particular way that some data is
  76. grouped. For example, a structure called 'X' might be defined as a word,
  77. followed by a pointer to another structure 'X', followed by a pointer to
  78. a structure 'Y', followed by a long word. By knowing a structure's
  79. template and where in memory such a structure is stored, it is a simple
  80. matter for the system or an application program to extract the data in
  81. that structure.
  82.  
  83. What kind of information can we find in various structures throughout the
  84. system's memory? Well, some interesting things are to be found, for
  85. example, in the Intuition-managed structures. With the program presented
  86. here, you'll be able to look at Screen, Window, and Gadget structures,
  87. among others. Information about any program in the system can be gained by
  88. looking at these structures, since everybody's windows, screens and gadgets
  89. are maintained in a kind of network where they can be accessed via pointers
  90. from other Screen, Window and Gadget structures. A pointer to the first
  91. Screen is all that is needed to find everything else, and that is found in
  92. the "IntuitionBase" structure, which, in turn, is found when the Intuition
  93. library is opened by a call to the OpenLibrary() function. (OpenLibrary()
  94. is in the Exec library, a pointer to which is found in memory location
  95. 000004, the only fixed location in the entire Amiga memory map. C-language
  96. startup code opens the Exec library.) All programs that use Intuition have
  97. their information in these structures, so through them you can learn
  98. things about any task currently running in the system.
  99.  
  100. A screen structure contains everything Intuition needs to know about a
  101. screen, like its size, title, number of bit-planes, a pointer to its
  102. gadgets, flags describing what kind of screen it is, the colours it's
  103. rendered in, etc. The screen structure points to a window structure for
  104. the first window on the screen. A window structure has a pointer that can
  105. point to another window structure, so that all windows in a screen are
  106. linked together. If there is more than one screen in the system (unless
  107. you have an application running that opens its own screen, the only
  108. screen will be the Workbench screen), there will be a pointer in the first
  109. screen structure to the next screen; any number of screens can be linked
  110. together in this way. In a window structure you'll find the usual size
  111. and colour information, along with an IDCMPFlags variable which describes
  112. what messages Intuition is getting from that window.
  113.  
  114. A pointer to the first gadget in a linked list of gadgets can also be found
  115. in the window structure. A gadget structure totally describes a gadget (a
  116. simple way to get input from the user through the mouse) - its position,
  117. size, type, imagery, etc. The gadget structure is set up by an application
  118. before the structure is submitted to Intuition, so the values within
  119. represent those that the programmer actually put into his code - in other
  120. words, a peek into a program's gadget structure can give some insight into
  121. how a program was written.  
  122.  
  123. Other structures of interest that are not implemented in Version 1.2 of
  124. Structure Browser: Image, Requester, Layer, Interrupt, MemChunk, MsgPort,
  125. Message, Task, VSprite, AnimOb. (Many of these structures, like Task and
  126. Interrupt, are difficult to monitor since the data within are constantly
  127. changing.)
  128.  
  129. The key to finding the memory location of any structure is the Library Base
  130. structures. Every shared library ("graphics.library", "intuition.library",
  131. "layers.library", to name a few) has a library base structure that contains
  132. pointers to structures of interest to routines in that library. The
  133. structures form a kind of network, since you can reach structures through
  134. pointers in other structures. In this network can be found every bit of
  135. data that the system cares anything about; a direct link to the the
  136. system's state of mind at any given moment. If we know the definitions for
  137. the system structures (there are over a hundred of them altogether), we can
  138. snoop around and discover anything we wish to know about what the system
  139. knows. And in the Amiga, the system knows a lot, because application
  140. software has to go through the system for just about anything it wants to
  141. do.
  142.  
  143.            The Structure Browser Program
  144.  
  145. The Structure Browser (SB from now on) makes it easy to snoop through many
  146. of the structures in the system. You start with a list of the library base
  147. structures; in the current version of the program, only IntuitionBase is
  148. available. To display the contents of the library base structure, just move
  149. the pointer to the library base name on the screen and press the left mouse
  150. button. The library base structure will immediately be displayed, showing
  151. each structure member's name (as defined in the standard Amiga header
  152. files) and its data type. In the case of the IntuitionBase structure, all
  153. members are pointers to other structures of importance; to display any of
  154. these, just click on its name as usual. This process can be repeated again
  155. in the new structure, to bring you to other structures of interest. You can
  156. always get to the structure you came from by clicking on the "Previous
  157. Level" gadget at the bottom left of the window. You can trace your steps as
  158. far back as you want, since the program works recursively (the number of
  159. levels deep you are is displayed in the heading at the top of the window).
  160. Structures that contain more members than will fit on the window show the
  161. first 16 members and display a gadget that says "(MORE)". You can go to the
  162. next page of structure members by clicking on (MORE), and go to the
  163. previous page by clicking on the "Previous Page" gadget. By going from
  164. structure to structure in this manner, it is easy to view information
  165. about programs that would be impossible to find out otherwise. For example
  166. - what kind of gadgets are being used in that neat commercial program? Are
  167. they gadgets at all? Did the programmer use a requester or a window for
  168. that prompt? Just by mousing around with SB, you can find it all out!
  169.  
  170. The data type for each structure member is shown in the same way that the
  171. members are declared in the C header files (the appropriate header file
  172. must be compiled - using the #include statement - with any C program that
  173. wants to refer to a system structure). These data types are standard in
  174. Amiga code, because they are `typedefs' that are set up in the header file
  175. "exec/types.h". The basic types are:
  176.  
  177. BYTE    - signed 8-bit value (char)
  178. UBYTE   - unsigned 8-bit value (unsigned char)
  179. SHORT   - signed 16-bit value (short)
  180. USHORT  - unsigned 16-bit value (unsigned short)
  181. LONG    - signed 32-bit value (long)
  182. ULONG   - unsigned 32-bit value (unsigned long)
  183.  
  184. Pointers to any of the above are denoted as in standard C syntax, with an
  185. asterisk (*). For example, a pointer to a SHORT would be denoted by SHORT *
  186. in the type field. Structure members that are pointers to other structures
  187. also use the C syntax; a pointer to a `Window' structure, for instance, is
  188. denoted by `struct Window *'. A structure member that is an actual
  189. structure, not a pointer to a structure, has no asterisk, and no value is
  190. given (it is contained within the structure being viewed, whose address is
  191. already shown).
  192.  
  193. Structure members that represent not pointers to other structures, but
  194. actual data that may be of interest, are displayed in various ways depending
  195. on their nature. These data can be simple numbers, like those giving a
  196. window's LeftEdge, TopEdge, Width and Height. The item of interest might be
  197. a byte, word or longword containing flags of some sort, like the flags
  198. indicating a window or gadget type. Or the data you're concerned with might
  199. just be an area of memory that contains a table of some sort or describes a
  200. graphic image. Simple data values, like LefEdge, etc. are shown in black on
  201. the SB window. Such structure members cannot be used to bring up any further
  202. information by pointing on them and clicking - nothing will happen if you do
  203. so. They are just what they appear; a number for you to see. The values in
  204. black are often just what you want to find out after getting to a structure
  205. of interest. When one of these values is used for containing flags of some
  206. sort, it is treated differently: you can click on it to get a list of what
  207. flags are set. An example might be a "smart refresh" window with sizing,
  208. close and drag system gadgets. The "Flags" member of such a window's
  209. structure, when selected, would show:
  210.  
  211.     WINDOWDRAG WINDOWSIZING WINDOWCLOSE SMART_REFRESH
  212.  
  213. (Like the member names, the flag names are those defined in the standard
  214. header files used for C or assembler program development.)
  215.  
  216. Another form of specialized output in SB is the hex dump. When a
  217. structure member is an array of values or a pointer to an area of memory
  218. like a bit-plane or image data, clicking on the member name causes a hex
  219. dump of the data to be displayed. If the data type is specified in the
  220. structure template, the data size is taken into account in the hex dump -
  221. the hex values are shown as either bytes, words, or long words.
  222.  
  223.               A Sample Tour
  224.  
  225. On paper, the process may sound rather involved, but using SB is a breeze.
  226. Here's an example of how you could find out the type of gadget used by a
  227. program that is currently running in the system. Let's use as an example
  228. the editor on which this article is being written - we'll take a look at
  229. the structure for this program's `page up' gadget to see how it is set up.
  230.  
  231. First, we have to run SB. That's not hard: type `sb' from the CLI. (or `run
  232. sb' if you want to keep the CLI available for launching other tasks while
  233. SB is running). SB will bring up a window that is the full width of the
  234. screen, but isn't full height, leaving a bit of the WorkBench screen
  235. visible at the top. On the window you will be prompted to select a library
  236. structure. Since only one choice is available in this version of the
  237. program, the decision isn't difficult: select "Intuition" by pointing with
  238. the mouse and clicking the left button. After clicking, a list of the
  239. "IntuitionBase" structure members will be displayed, with their types and
  240. values shown on the right. All members are pointers to the indicated
  241. structures, and the top two are parenthesized, meaning that those structure
  242. types are not available in this version of the program. To keep the
  243. magazine listing reasonably short, we only implemented a few key structure
  244. types; pointers to unimplemented structures are parenthesized, and clicking
  245. on them has no effect.
  246.  
  247. Now, on with our travels to the gadget structure of interest. Since the
  248. program we're interested in has a window on the WorkBench screen, we must
  249. get to that screen's structure first. We can get there by clicking on the
  250. "ActiveScreen" member in the IntuitionBase structure, since the active
  251. screen - the one we're currently working on - is the WorkBench screen. One
  252. click, and up comes the first page of the structure members in the WorkBench
  253. screen structure. You can tell you've got the right screen by looking at the
  254. member called "Title"; to the right it should say "Workbench Screen". To see
  255. more screen members, you can click on the "(MORE)" gadget that has appeared
  256. at the bottom of the window, and then click on "Previous Page" to get back.
  257. The second member of the screen structure is called "FirstWindow", and it
  258. points to the first window structure in a linked list containing all windows
  259. on the screen.
  260.  
  261. Click on "FirstWindow" and a window structure will be displayed. It may not
  262. be the window we're looking for, in fact it might be the window belonging
  263. to SB itself. The "Title" member will tell you what window you're looking
  264. at, since it will say exactly what is on the title bar of the corresponding
  265. window. You'll also notice other items of interest in this structure, like
  266. the window's dimensions and the flags set for the window. Try clicking on
  267. the "Flags" member to show the window flags. Even if you're not familiar
  268. with Intuition programming, the names of the flags should suggest their
  269. purpose. Now, to get to the next window structure in the list, just click
  270. on the first member of the window structure, the one called "NextWindow".
  271. You'll now have the structure for the next window displayed - continue
  272. chaining through windows like this until you get to the one you want. For
  273. our sample structure tour, we would stop when we got to the window
  274. belonging the text editor.
  275.  
  276. Now that we've found the window structure we want, let's look for a pointer
  277. to the gadget list attached to the window. There's nothing like that on the
  278. first page, so click the "(MORE)" gadget to see more window members. About
  279. half way down is the member "FirstGadget", which points to a gadget
  280. structure (its type is `struct Gadget *', meaning a pointer to a Gadget
  281. structure). Click there, and up comes the first in a linked list of gadget
  282. structures for that window. By looking at the LeftEdge and Top variables,
  283. you can see the position of the gadget on the screen. To go to the next
  284. gadget structure in the list, just click on the first member, "NextGadget".
  285. You can chain through the program's entire gadget list this way, stopping
  286. when you wish to examine the flag variables "Flags, "Activation", or
  287. "GadgetType". GadgetType will tell you if the gadget is a BOOLGADGET
  288. (boolean), PROPGADGET (proportional), or STRGADGET (string). Eventually, we
  289. get to a gadget with its TopEdge at 20, and its LeftEdge at -16. Since the
  290. GRELRIGHT flag is set in the Flags variable, we know the LeftEdge value
  291. indicates that the left edge of the gadget is 16 pixels to the left of the
  292. window's right border. That's the `page up' gadget that we're looking for.
  293. We can examine the Gadget structure to see exactly how we could create a
  294. similar gadget in our own programs. (Using the same imagery as someone
  295. else's gadget in your programs might be considered a violation of
  296. copyright, but the current version of SB doesn't support Image structures
  297. anyway so there'll be no "Don't try this at home, kids!" warning here.)
  298.  
  299. Structure Browser doesn't support all the system structures as it stands
  300. now - there are just too many and the program would fill the entire
  301. magazine. Rather, we have put in some of the more interesting Intuition
  302. structures and we plan on adding more for version 2.0 of SB, which will be
  303. found on The Transactor's first Amiga disk, and will be uploaded to
  304. Compuserve's AmigaForum. The program is designed so that it is easy to add
  305. new structures as you wish - if you have access to the "include" files for
  306. development (or the listings of them in the ROM Kernal manual), it should
  307. be easy for you to add whatever structures you're interested in to the
  308. program. Information about doing this is given later in the article. SB is
  309. public domain, so you're free to use and modify it as you wish; if you do
  310. add new structures, though, please use the standard Amiga member names and
  311. types exactly as they appear in the include files. We plan to see how far
  312. the SB concept of system structure browsing can be taken - a few ideas for
  313. enhancements are given later in this article.
  314.  
  315.                  Applications for SB
  316.  
  317. By now you've probably seen that SB is a great tool for learning about
  318. the Amiga's internal data structures. But there are actually quite a few
  319. good reasons to have SB around on your most-used disk - maybe even in the
  320. C directory of your usual Workbench or development disk.
  321.  
  322. For one thing, SB makes a very handy reference to the structure templates
  323. themselves. It's easier to bring up SB and click to a structure than to
  324. look up that structure definition in the ROM Kernal manual. And if you
  325. don't have the manual, it's easier than looking through lots of include
  326. files. If you don't have the include files, it's the only way!
  327.  
  328. SB can also be used as a debugging tool: if your program is acting
  329. strange, you can peek at Intuition's view of your windows, gadgets, etc.,
  330. to make sure they are properly set up and linked together the way you
  331. intended. You can look at these things at any time during your program's
  332. execution to see what happens when certain actions are taken; kind of
  333. like a trace, but only pertaining to the program's interaction with the
  334. operating system.
  335.  
  336. Another benefit of SB is that you can use it to learn programming
  337. techniques by looking at how other applications have set up their
  338. structures to achieve certain effects. By investigating the structures of
  339. known system entities, you can see what effect certain flags and variables
  340. have on their behaviour. If you're curious about the tricks that some
  341. program is using, just take a browse through its gadgets and windows. For
  342. instance, did you know that Workbench uses a borderless, backdrop window
  343. that lies on the Workbench screen just below the screen title? We didn't
  344. either, until we used SB to look at the Workbench window structure. You
  345. can get some good ideas from other people's use of Intuition's resources.
  346.  
  347.               Future Versions of SB
  348.  
  349. Our main goal for SB is to eventually have it encompass all system
  350. structures and flags. The program can be expected to grow in size
  351. considerably, but it will be worth it for a total map of the system's
  352. inner thoughts. But besides expanding in scope, there could also be more
  353. flexibility in the ways that lowest-level data types are displayed. For
  354. example, graphic data could be displayed not as a hex-dump, but as the
  355. actual image that it defines. Some values, like the mouse's X and Y
  356. coordinates that are found in a window structure, could be updated
  357. frequently to give readings that are always up-to-date. The hex dump
  358. should also display ASCII equivalents of the bytes. Perhaps a less
  359. immediately-implemented feature will be the saving of image and BitMap
  360. data to disk as IFF-format files. There should be a way to save any
  361. structure and its current values to a file as well, perhaps as C or
  362. assembler code for easy inclusion in your own programs. If anyone has any
  363. good ideas, let us know. Or better yet, implement them - we don't want
  364. all the glory for ourselves! (read: we don't want to do all the work
  365. ourselves!)
  366.  
  367.            Program Listing Notes
  368.  
  369. The C source for SB is broken into several files, each with its own purpose.
  370. The mainline and general functions are in the file "sb.c". The intuition
  371. calls and all functions dealing with the program's user interface is in the
  372. file "sbio.c". The other files contain the individual routines to handle
  373. different structure types. "sbwindow.c", "sbscreen.c", and "sbgadget.c"
  374. contain the functions that handle the structures their names suggest.
  375. "sbgfx.c" handles the graphics library-related structures, RastPort and
  376. BitMap. In addition, a header file, "sb.h", contains various #define
  377. statements and a structure definition - it should be stored in a
  378. subdirectory called "header". All of these separate files can be compiled
  379. with Manx Aztec C using "make" and the makefile provided. The makefile takes
  380. advantage of Manx's pre-compiled header file capability to speed up
  381. compilation by not having to re-compile "intuition.h" in each of the six
  382. source files. If you are using this method, you can delete the #include at
  383. the top of each source file as indicated in the comment. For users of
  384. Lattice C, just compile all six files and link them normally - don't worry
  385. about the makefile.
  386.  
  387. When entering the program, take extra care in entering the the `structdata'
  388. arrays in each structure print function. The first character of each member
  389. name is either a space, minus, or left parenthesis; it is important to use
  390. the correct one. Also, if you use the wrong data size constant (like putting
  391. in INTSIZE where it should be PTRSIZE), you will get bad results when you
  392. try to display that structure, or worse yet, a software error.
  393.  
  394. NOTE: in version 1.2 (and later) of SB, a trap-handler is installed to
  395.       catch CPU exceptions and eliminate most software errors.
  396.  
  397.                  Program Notes
  398.  
  399. SB is quite useful as it stands, but you may want to modify it to
  400. incorporate some other structures that you're interested in. If you do,
  401. here is some explanation of the program to help you out. The specifics are
  402. up to you; have a ball, hackers!
  403.  
  404. The principle behind SB is very simple. A specialized function exists for
  405. each kind of structure. If a structure contains more members than will fit
  406. on one page, there is a function for each subsequent page. The function is
  407. passed a pointer to the structure (and an offset, in the case of
  408. multiple-page structures), and it prints the structure's members, types and
  409. values, then waits for input. (The actual output and input is handled by
  410. functions in "sbio.c", but more on those later.) Depending on the member
  411. selected by the user, an appropriate routine is called to print that
  412. structure's members and again wait for input. It may be that a routine
  413. calls itself, as when chaining through a linked list of like structures. In
  414. any case, each selection brings the program one level of nesting deeper,
  415. and the only way to go up a level is by the user clicking the "Previous
  416. Level" or "Previous Page" gadget, causing the return from a function.
  417. Besides functions that handle specific structures, there are the more
  418. general output functions that display hex dumps or flags - these are in the
  419. file "sb.c". The function used to tell the output function in "sbio.c" what
  420. to display is called put(), and is also in "sb.c" - it is called by all the
  421. structure output functions and is passed a pointer to the structure and a
  422. pointer to an array of special "StructData" structures. Setting up this
  423. array is the key to adding more structures to SB's repetoire.
  424.  
  425. A "StructData" structure is defined in the file "sb.h" seen in the listing.
  426. It contains information that SB needs to know about a structure member: its
  427. name, type, print option, and size. The name and type are just pointers to
  428. strings for display. The print type is needed so that put() knows how to
  429. print the member's value - as a byte, short, or long, signed or unsigned, or
  430. as a string or pointer. See the put() function to see how the print codes
  431. are interpreted. The other member of a struct StructData, the data size,
  432. indicates the number of bytes used by the structure member. The constants
  433. BYTESIZE, INTSIZE, and PTRSIZE are defined in "sb.h" to specify the common
  434. sizes 1, 2, and 4. When the member is a structure (not a pointer to a
  435. structure, but an instance of the structure itself), use the SZ macro
  436. defined in "sb.h" to calculate the size of the structure, e.g. SZ(View)
  437. instead of sizeof(struct View).
  438.  
  439. By looking at the functions PrWindow(), PrScreen(), and PrGadget() as
  440. examples, you should have no difficulty adding the functions to display
  441. system structures of your interest. If you add a new structure, you'll have
  442. to allow the user to select it from another structure by removing the
  443. parenthesis from around the member name and type. An opening parenthesis at
  444. the start of a member name instead of a space prevents that member from
  445. being selected by the user (doesn't make it a gadget). Just remove these
  446. parenthesis from all functions whose structure contains a pointer to your
  447. newly-implemented structure, and add a call to your new function in the
  448. SWITCH statement. Again, refer to the functions mentioned above for
  449. clarification.
  450.  
  451. In the print function for any new structure you've added to the program,
  452. set up a static 'structdata' array of StructData structures (try saying
  453. that three times quickly!) as in the other functions. Members names should
  454. begin with a space for flags, arrays, or pointers to structures that
  455. SB can handle (i.e. anything for which a print function exists), a minus
  456. (-) for simple data elements that will be rendered in black and will not be
  457. selectable by the user, or a parenthesis for pointers to structures that
  458. are not supported by the program.
  459.  
  460. The output of members to the window and the input of a response from the
  461. user is handled by the same function, GetChoice(). Selectable structure
  462. members are implemented as Intuition gadgets that have no rendering other
  463. than the associated IntuiText. An array of 16 IntuiText structures is set up
  464. to contain the text for each line printed to the window. An array of 16
  465. boolean gadgets, each pointing to a different IntuiText structure, is also
  466. declared. Gadget structures also exist for the "Previous Level" and
  467. "(MORE)" gadgets that appear on the window.
  468.  
  469. When GetChoice() is called, it calls Redisplay() to put up the structure
  470. member names and build the required list of gadgets. Redisplay() first
  471. removes all existing gadgets except the first in the gadget list, the
  472. "Previous Level" gadget (BackGadg). Depending on the number of structure
  473. members to be displayed, up to 16 passes through a loop are made to either
  474. print an IntuiText or add the associated gadget to the gadget list. After
  475. the loop, the "(MORE)" gadget (MoreGadg) is added if there are more than 16
  476. structure members to display. Finally, a call to the Intuition function
  477. RefreshGadgets() displays the gadget text on the window. After Redisplay()
  478. has done it job, GetChoice() waits for an IDCMP (Intuition Direct
  479. Communication Message Port) event, which will signify that the user has
  480. selected a gadget. If the window close gadget was selected, CloseOut() is
  481. called to close up libraries and the open window, then call exit() to fix
  482. up the stack and return to CLI. if another gadget was selected, the
  483. gadget's ID is returned to the caller of GetChoice(). The IDs of the
  484. structure member gadgets are their ordinal values - 1 for the first and so
  485. on. The "Previous Level" gadget has an ID of 0, and the "(MORE)" gadget's
  486. ID is the constant MOREGADG, defined as 25 in "sb.h".
  487.  
  488.               To SB 2.0 ... And Beyond!
  489.  
  490. As you've read, SB can be expected to expand well beyond its current
  491. capabilities. If anyone adds new structures, flags, or features to SB, we
  492. would be happy to incorporate the changes in the latest version for wide
  493. public-domain distribution. We will play `keeper of the source' and attempt
  494. to coordinate all improvements to maintain the latest, greatest SB which
  495. will be uploaded to Compuserve and other services, and included on our
  496. public-domain Amiga disks (probably available next issue).
  497.  
  498. Meanwhile, have fun picking Intuition's brains with SB 1.2, and we'll see
  499. you next issue!
  500.